package cn.fintecher.pangolin.service.dataimp.service;

import cn.fintecher.pangolin.common.enums.*;
import cn.fintecher.pangolin.common.exception.BadRequestException;
import cn.fintecher.pangolin.common.model.*;
import cn.fintecher.pangolin.common.utils.BeanUtils;
import cn.fintecher.pangolin.common.utils.ExportDataToExcelUtil;
import cn.fintecher.pangolin.common.utils.Snowflake;
import cn.fintecher.pangolin.common.utils.ZWDateUtil;
import cn.fintecher.pangolin.entity.elastic.ImportExcelConfigItem;
import cn.fintecher.pangolin.entity.mysql.CaseInfo;
import cn.fintecher.pangolin.entity.mysql.PaymentCheck;
import cn.fintecher.pangolin.entity.mysql.ProcessApplication;
import cn.fintecher.pangolin.entity.mysql.ProcessFlowNode;
import cn.fintecher.pangolin.service.dataimp.client.WebSocketClient;
import cn.fintecher.pangolin.service.dataimp.model.request.ApprovalExportRequest;
import cn.fintecher.pangolin.service.dataimp.model.request.ApprovalImportDataRequest;
import cn.fintecher.pangolin.service.dataimp.repository.CaseInfoRepository;
import cn.fintecher.pangolin.service.dataimp.repository.PaymentCheckRepository;
import cn.fintecher.pangolin.service.dataimp.repository.ProcessApplicationRepository;
import cn.fintecher.pangolin.service.dataimp.request.ExportPaymentCheck;
import com.google.common.collect.Lists;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author wangxiangdong
 * @Description 审批管理导入导出
 * @Date 2019/10/17 9:47
 **/
@Service
public class ApprovalExportService {

    @Autowired
    private BaseService baseService;

    @Autowired
    private ProcessApplicationRepository processApplicationRepository;

    @Autowired
    private WebSocketClient webSocketClient;

    @Autowired
    private ApprovalImportDataService approvalImportDataService;

    @Autowired
    private CaseInfoRepository caseInfoRepository;

    @Autowired
    private PaymentCheckRepository paymentCheckRepository;

    @Async
    @Transactional
    public void getExportTitle(ApprovalExportRequest request, String token) {
        UserModel userByToken = baseService.getUserByToken(token);
        UploadFile uploadFile = null;
        TaskBoxModel taskBoxModel = new TaskBoxModel();
        Snowflake snowflake = new Snowflake((int) (Thread.currentThread().getId() % 1024));
        taskBoxModel.setId(String.valueOf(snowflake.next()));
        baseService.sendTaskBoxMessage(taskBoxModel, TaskBoxType.EXPORT, TaskBoxStatus.UN_FINISH, null, null, userByToken, ZWDateUtil.getNowDateTime(), null, "申请类信息导出");
        List<Class<?>> objClassList = new ArrayList<>();
        String fieldName = "";
        try {
            List<ProcessApplication> processApplicationList = Lists.newArrayList(processApplicationRepository.findAll(request.generateBooleanBuilder()));
            switch (request.getFlowType()) {
                case DERATE_APPLY:
                    objClassList.add(DerateAmountModel.class);
                    fieldName = fieldName.concat("减免申请导出_").concat(String.valueOf(System.currentTimeMillis())).concat(".xlsx");
                    List<DerateAmountModel> dataList = getDerateAmountData(processApplicationList);
                    uploadFile = exportData(taskBoxModel, userByToken, objClassList, dataList, fieldName);
                    break;
                case REPORT_CASE_APPLY:
                    fieldName = fieldName.concat("报案申请导出_").concat(String.valueOf(System.currentTimeMillis())).concat(".xlsx");
                    objClassList.add(ReportCaseModel.class);
                    List<ReportCaseModel> reportCaseData = getReportCaseData(processApplicationList);
                    uploadFile = exportData(taskBoxModel, userByToken, objClassList, reportCaseData, fieldName);
                    break;
                case CHECK_MATERIAL_APPLY:
                    fieldName = fieldName.concat("申请材料导出_").concat(String.valueOf(System.currentTimeMillis())).concat(".xlsx");
                    objClassList.add(ApplyMaterialModel.class);
                    List<ApplyMaterialModel> checkMaterialData = getCheckMaterialData(processApplicationList);
                    uploadFile = exportData(taskBoxModel, userByToken, objClassList, checkMaterialData, fieldName);
                    break;
                case LEAVE_CASE_APPLY:
                    fieldName = fieldName.concat("留案导出_").concat(String.valueOf(System.currentTimeMillis())).concat(".xlsx");
                    objClassList.add(LeaveCaseModel.class);
                    List<LeaveCaseModel> leaveCaseData = getLeaveCaseData(processApplicationList);
                    uploadFile = exportData(taskBoxModel, userByToken, objClassList, leaveCaseData, fieldName);
                    break;
                default:
                    throw new BadRequestException(null, "apply", "apply.is.not.exist");
            }
        } catch (Exception e) {
            e.printStackTrace();
            baseService.sendTaskBoxMessage(taskBoxModel, TaskBoxType.EXPORT, TaskBoxStatus.FAILURE, uploadFile.getId(), uploadFile.getOriginalName(), userByToken, null, ZWDateUtil.getNowDateTime(), "申请类信息导出");
        }
        baseService.sendTaskBoxMessage(taskBoxModel, TaskBoxType.EXPORT, TaskBoxStatus.FINISHED, uploadFile.getId(), uploadFile.getOriginalName(), userByToken, null, ZWDateUtil.getNowDateTime(), "申请类信息导出");
    }


    /**
     * @Author wangxiangdong
     * @Description 减免申请导出数据model转换
     * @Date 2019/10/17 14:48
     **/
    private List<DerateAmountModel> getDerateAmountData(List<ProcessApplication> processApplicationList) {
        List<DerateAmountModel> models = new ArrayList<>();
        for (ProcessApplication processApplication : processApplicationList) {
            DerateAmountModel derateAmountModel = new DerateAmountModel();
            BeanUtils.copyProperties(processApplication, derateAmountModel);
            models.add(derateAmountModel);
            processApplication.setExportState(ExportState.EXPORTED);
        }
        if (processApplicationList.size() > 0) {
            processApplicationRepository.saveAll(processApplicationList);
        }
        return models;
    }

    /**
     * @Author wangxiangdong
     * @Description 报案申请导出model数据转换
     * @Date 2019/10/17 14:29
     **/
    private List<ReportCaseModel> getReportCaseData(List<ProcessApplication> processApplicationList) {
        List<ReportCaseModel> models = new ArrayList<>();
        for (ProcessApplication processApplication : processApplicationList) {
            ReportCaseModel reportCaseModel = new ReportCaseModel();
            BeanUtils.copyProperties(processApplication, reportCaseModel);
            models.add(reportCaseModel);
            processApplication.setExportState(ExportState.EXPORTED);
        }
        if (processApplicationList.size() > 0) {
            processApplicationRepository.saveAll(processApplicationList);
        }
        return models;
    }

    /**
     * @Author wangxiangdong
     * @Description 申请材料导出model
     * @Date 2019/10/17 14:08
     **/
    private List<ApplyMaterialModel> getCheckMaterialData(List<ProcessApplication> processApplications) {
        List<ApplyMaterialModel> models = new ArrayList<>();
        for (ProcessApplication processApplication : processApplications) {
            ApplyMaterialModel applyMaterialModel = new ApplyMaterialModel();
            BeanUtils.copyProperties(processApplication, applyMaterialModel);
            DataDictModel model1 = new DataDictModel();
            model1.setClassName("ApplyFileContent");
            model1.setCode(processApplication.getApplyContent().name());
            String oneDataDict = webSocketClient.getOneDataDict(model1).getBody();
            if (Objects.nonNull(oneDataDict)) {
                applyMaterialModel.setApplyContent(oneDataDict);
            }
            models.add(applyMaterialModel);
            processApplication.setExportState(ExportState.EXPORTED);
        }
        if (processApplications.size() > 0) {
            processApplicationRepository.saveAll(processApplications);
        }
        return models;
    }

    /**
     * @Author wangxiangdong
     * @Description 转换留案导出数据model
     * @Date 2019/10/17 10:32
     **/
    private List<LeaveCaseModel> getLeaveCaseData(List<ProcessApplication> processApplications) {
        List<LeaveCaseModel> models = new ArrayList<>();
        for (ProcessApplication processApplication : processApplications) {
            LeaveCaseModel leaveCaseModel = new LeaveCaseModel();
            BeanUtils.copyProperties(processApplication, leaveCaseModel);
            models.add(leaveCaseModel);
            processApplication.setExportState(ExportState.EXPORTED);
        }
        if (processApplications.size() > 0) {
            processApplicationRepository.saveAll(processApplications);
        }
        return models;
    }

    /**
     * 导出数据
     * @param objClassList
     * @param dataList
     * @param fileName
     */
    private UploadFile exportData(TaskBoxModel taskBoxModel, UserModel userByToken, List<Class<?>> objClassList, List<?> dataList, String fileName) {
        List<String> list = new ArrayList<>();
        List<String> properties = new ArrayList<>();
        String filePath = FileUtils.getTempDirectoryPath();
        filePath = filePath.concat(fileName);
        UploadFile file = null;
        List<CaseInfoPropertyResponse> responses = ExportDataToExcelUtil.getObjejctProperty(objClassList);
        responses.forEach(response -> {
            list.add(response.getName());
            properties.add(response.getAttribute());
        });
        String[] title = new String[list.size()];
        list.toArray(title);
        String[] property = new String[list.size()];
        properties.toArray(property);
        try {
            ExportDataToExcelUtil.exportToExcel(dataList, title, property, filePath);
            file = baseService.getFileUrl(filePath);
        } catch (Exception e) {
            e.printStackTrace();
            baseService.sendTaskBoxMessage(taskBoxModel, TaskBoxType.EXPORT, TaskBoxStatus.FAILURE, file.getId(), file.getOriginalName(), userByToken, null, ZWDateUtil.getNowDateTime(), "申请类信息导出");
        }
        return file;
    }

    /**
     * @Author wangxiangdong
     * @Description 导入审批
     * @Date 2019/10/18 9:27
     **/
    @Transactional
    public void approvalByImportData(ApprovalImportDataRequest request, UserModel userModel) {
        InputStream inputStream = approvalImportDataService.readFile(request.getFileId());
        List<Class<?>> objClassList = new ArrayList<>();
        switch (request.getFlowType()) {
            case DERATE_APPLY:
                objClassList.add(DerateAmountModel.class);
                dealWithDearteCaseImport(objClassList, inputStream, request.getFlowType());
                break;
            case REPORT_CASE_APPLY:
                objClassList.add(ReportCaseModel.class);
                dealWithReportCaseImport(objClassList, inputStream,request.getFlowType());
                break;
            case LEAVE_CASE_APPLY:
                objClassList.add(LeaveCaseModel.class);
                dealWithLeaveCaseImport(objClassList, inputStream,request.getFlowType());
                break;
            default:
                break;
        }
    }

    private void dealWithDearteCaseImport(List<Class<?>> objClassList, InputStream inputStream, FlowType flowType) {
        List<Map<String, String>> sheetDataList = approvalImportDataService.parseApprovalImportData(inputStream);
        Map<String, ImportExcelConfigItem> headMap = approvalImportDataService.excelConfigItemToMap(sheetDataList, inputStream, objClassList);
        sheetDataList.remove(sheetDataList.get(0));
        List<String> errorList = new ArrayList<>();
        List<DerateAmountModel> derateAmountModelList = new ArrayList<>();
        Long rowIndex = 1L;
        List<ProcessApplication> processApplicationList = new ArrayList<>();
        for (Map<String, String> map : sheetDataList) {
            DerateAmountModel object = new DerateAmountModel();
            for (Map.Entry<String, String> cellUnit : map.entrySet()) {
                String cellValue = cellUnit.getValue();
                ImportExcelConfigItem importExcelConfigItem = headMap.get(cellUnit.getKey());
                approvalImportDataService.parseCellMap(object, cellValue, importExcelConfigItem, errorList, rowIndex, 1);
            }
            derateAmountModelList.add(object);
            rowIndex++;
        }
        derateAmountModelList.forEach(derateAmountModel -> {
            ProcessApplication processApplication = processApplicationRepository.findById(derateAmountModel.getId()).orElseThrow(()->new BadRequestException(null,"dealWithLeaveCaseImport","application.is.not.found"));
            if(StringUtils.isNotBlank(derateAmountModel.getApprovedStatus()) && Objects.equals(derateAmountModel.getApprovedStatus().trim(),"是")){
                processApplication.setApprovalStage(ApprovalStage.APPROVED_PASS);
                Set<ProcessFlowNode> processFlowNodes = processApplication.getProcessFlowNodes().stream().filter(processFlowNode -> Objects.equals(processFlowNode.getApprovalStatus(),ApprovalStatus.WAIT_APPROVAL)).collect(Collectors.toSet());
                setProvessFlowNode(processFlowNodes,ApprovalResult.APPROVED_PASS,derateAmountModel.getApprovedMemo());
                sendApproverResultMessage(flowType,ApprovalResult.APPROVED_PASS,processApplication.getApplyId(),processApplication.getPersonalName());
            }
            if(StringUtils.isNotBlank(derateAmountModel.getApprovedStatus()) && Objects.equals(derateAmountModel.getApprovedStatus().trim(),"否")){
                processApplication.setApprovalStage(ApprovalStage.APPROVED_REJECT);
                Set<ProcessFlowNode> processFlowNodes = processApplication.getProcessFlowNodes().stream().filter(processFlowNode -> Objects.equals(processFlowNode.getApprovalStatus(),ApprovalStatus.WAIT_APPROVAL)).collect(Collectors.toSet());
                setProvessFlowNode(processFlowNodes,ApprovalResult.APPROVED_REJECT,derateAmountModel.getApprovedMemo());
                sendApproverResultMessage(flowType,ApprovalResult.APPROVED_REJECT,processApplication.getApplyId(),processApplication.getPersonalName());
            }
            processApplicationList.add(processApplication);
        });
        if(processApplicationList.size()>0){
            processApplicationRepository.saveAll(processApplicationList);
        }
    }

    private void dealWithReportCaseImport(List<Class<?>> objClassList, InputStream inputStream,FlowType flowType) {
        List<Map<String, String>> sheetDataList = approvalImportDataService.parseApprovalImportData(inputStream);
        Map<String, ImportExcelConfigItem> headMap = approvalImportDataService.excelConfigItemToMap(sheetDataList, inputStream, objClassList);
        sheetDataList.remove(sheetDataList.get(0));
        List<String> errorList = new ArrayList<>();
        List<ReportCaseModel> reportCaseModels = new ArrayList<>();
        Long rowIndex = 1L;
        List<ProcessApplication> processApplicationList = new ArrayList<>();
        for (Map<String, String> map : sheetDataList) {
            ReportCaseModel object = new ReportCaseModel();
            for (Map.Entry<String, String> cellUnit : map.entrySet()) {
                String cellValue = cellUnit.getValue();
                ImportExcelConfigItem importExcelConfigItem = headMap.get(cellUnit.getKey());
                approvalImportDataService.parseCellMap(object, cellValue, importExcelConfigItem, errorList, rowIndex, 1);
            }
            reportCaseModels.add(object);
            rowIndex++;
        }
        reportCaseModels.forEach(reportCaseModel -> {
            ProcessApplication processApplication = processApplicationRepository.findById(reportCaseModel.getId()).orElseThrow(()->new BadRequestException(null,"dealWithLeaveCaseImport","application.is.not.found"));
            if(StringUtils.isNotBlank(reportCaseModel.getApprovedStatus()) && Objects.equals(reportCaseModel.getApprovedStatus().trim(),"是")){
                processApplication.setApprovalStage(ApprovalStage.APPROVED_PASS);
                Set<ProcessFlowNode> processFlowNodes = processApplication.getProcessFlowNodes().stream().filter(processFlowNode ->Objects.equals(processFlowNode.getApprovalStatus(),ApprovalStatus.WAIT_APPROVAL)).collect(Collectors.toSet());
                setProvessFlowNode(processFlowNodes,ApprovalResult.APPROVED_PASS,reportCaseModel.getReportRemark());
                sendApproverResultMessage(flowType,ApprovalResult.APPROVED_PASS,processApplication.getApplyId(),processApplication.getPersonalName());
            }
            if(StringUtils.isNotBlank(reportCaseModel.getApprovedStatus()) && Objects.equals(reportCaseModel.getApprovedStatus().trim(),"否")){
                processApplication.setApprovalStage(ApprovalStage.APPROVED_REJECT);
                Set<ProcessFlowNode> processFlowNodes = processApplication.getProcessFlowNodes().stream().filter(processFlowNode ->Objects.equals(processFlowNode.getApprovalStatus(),ApprovalStatus.WAIT_APPROVAL)).collect(Collectors.toSet());
                setProvessFlowNode(processFlowNodes,ApprovalResult.APPROVED_REJECT,reportCaseModel.getReportRemark());
                sendApproverResultMessage(flowType,ApprovalResult.APPROVED_REJECT,processApplication.getApplyId(),processApplication.getPersonalName());
            }
            processApplicationList.add(processApplication);
        });
        if(processApplicationList.size()>0){
            processApplicationRepository.saveAll(processApplicationList);
        }
    }


    private void dealWithLeaveCaseImport(List<Class<?>> objClassList, InputStream inputStream,FlowType flowType) {
        List<Map<String, String>> sheetDataList = approvalImportDataService.parseApprovalImportData(inputStream);
        Map<String, ImportExcelConfigItem> headMap = approvalImportDataService.excelConfigItemToMap(sheetDataList, inputStream, objClassList);
        sheetDataList.remove(sheetDataList.get(0));
        List<String> errorList = new ArrayList<>();
        List<LeaveCaseModel> leaveCaseModelList = new ArrayList<>();
        Long rowIndex = 1L;
        List<ProcessApplication> processApplicationList = new ArrayList<>();
        for (Map<String, String> map : sheetDataList) {
            LeaveCaseModel object = new LeaveCaseModel();
            for (Map.Entry<String, String> cellUnit : map.entrySet()) {
                String cellValue = cellUnit.getValue();
                ImportExcelConfigItem importExcelConfigItem = headMap.get(cellUnit.getKey());
                approvalImportDataService.parseCellMap(object, cellValue, importExcelConfigItem, errorList, rowIndex, 1);
            }
            leaveCaseModelList.add(object);
            rowIndex++;
        }
        leaveCaseModelList.forEach(leaveCaseModel -> {
            ProcessApplication processApplication = processApplicationRepository.findById(leaveCaseModel.getId()).orElseThrow(()->new BadRequestException(null,"dealWithLeaveCaseImport","application.is.not.found"));
            if(StringUtils.isNotBlank(leaveCaseModel.getApprovedStatus()) && Objects.equals(leaveCaseModel.getApprovedStatus().trim(),"是")){
                processApplication.setApprovalStage(ApprovalStage.APPROVED_PASS);
                Set<ProcessFlowNode> processFlowNodes = processApplication.getProcessFlowNodes().stream().filter(processFlowNode ->Objects.equals(processFlowNode.getApprovalStatus(),ApprovalStatus.WAIT_APPROVAL)).collect(Collectors.toSet());
                setProvessFlowNode(processFlowNodes,ApprovalResult.APPROVED_PASS,leaveCaseModel.getApprovedMemo());
                executeLeaveCase(processApplication.getCaseId(),leaveCaseModel.getEndCaseDate());
                sendApproverResultMessage(flowType,ApprovalResult.APPROVED_PASS,processApplication.getApplyId(),processApplication.getPersonalName());
            }
            if(StringUtils.isNotBlank(leaveCaseModel.getApprovedStatus()) && Objects.equals(leaveCaseModel.getApprovedStatus().trim(),"否")){
                processApplication.setApprovalStage(ApprovalStage.APPROVED_REJECT);
                Set<ProcessFlowNode> processFlowNodes = processApplication.getProcessFlowNodes().stream().filter(processFlowNode -> Objects.equals(processFlowNode.getApprovalStatus(),ApprovalStatus.WAIT_APPROVAL)).collect(Collectors.toSet());
                setProvessFlowNode(processFlowNodes,ApprovalResult.APPROVED_REJECT,leaveCaseModel.getApprovedMemo());
                sendApproverResultMessage(flowType,ApprovalResult.APPROVED_REJECT,processApplication.getApplyId(),processApplication.getPersonalName());
            }
            processApplicationList.add(processApplication);
        });
        if(processApplicationList.size()>0){
            processApplicationRepository.saveAll(processApplicationList);
        }
    }

    /**
     * @Author wangxiangdong
     * @Description 审批通过 留案操作
     * @Date 2019/9/28 14:20
     **/
    private void executeLeaveCase(String caseId, Date endCaseDate) {
        CaseInfo caseInfo = caseInfoRepository.findById(caseId).orElseThrow(()->new BadRequestException(null,"executeLeaveCase","case.is.not.exists"));
        caseInfo.setLeaveFlag(CaseLeaveFlag.HAS_LEAVE);
        caseInfo.setEndCaseDate(endCaseDate);
        caseInfoRepository.save(caseInfo);
    }

    /**
     * @Author wangxiangdong
     * @Description 发送审批结果消息
     * @Date 2019/10/16 15:39
     **/
    private void sendApproverResultMessage(FlowType flowType,ApprovalResult approvalResult,String applyId,String personalName){
        String approveResultStr ;
        if(Objects.equals(ApprovalResult.APPROVED_PASS,approvalResult)){
            approveResultStr = "已通过";
        }else{
            approveResultStr = "已拒绝";
        }
        switch (flowType) {
            case PUBLIC_CASE_APPLY:
                baseService.sendMessageToOne(MessageType.APPLY_APPROVE_MSG, "公共案件申请审批结果", "客户:" + personalName + "的公共案件申请审批" + approveResultStr, applyId);
                break;
            case PUBLIC_DISTRIBUTE_CASE_APPLY:
                baseService.sendMessageToOne(MessageType.APPLY_APPROVE_MSG, "公共案件分配申请审批结果", "客户:" + personalName + "的公共案件分配申请审批" + approveResultStr, applyId);
                break;
            case LEAVE_CASE_APPLY:
                baseService.sendMessageToOne(MessageType.APPLY_APPROVE_MSG, "留案申请审批结果", "客户:" + personalName + "的留案案件申请审批" + approveResultStr, applyId);
                break;
            case CHECK_MATERIAL_APPLY:
                baseService.sendMessageToOne(MessageType.APPLY_APPROVE_MSG, "资料申请审批结果", "客户:" + personalName + "的资料申请审批" + approveResultStr, applyId);
                break;
            case REPORT_CASE_APPLY:
                baseService.sendMessageToOne(MessageType.APPLY_APPROVE_MSG, "报案申请审批结果", "客户:" + personalName + "的报案申请审批" + approveResultStr, applyId);
                break;
            case DERATE_APPLY:
                baseService.sendMessageToOne(MessageType.APPLY_APPROVE_MSG, "减免申请审批结果", "客户:" + personalName + "的减免申请审批" + approveResultStr, applyId);
                break;
            case VISIT_APPLY:
                baseService.sendMessageToOne(MessageType.APPLY_APPROVE_MSG, "外访申请审批结果", "客户:" + personalName + "的外访申请审批" + approveResultStr, applyId);
                break;
            case LETTER_PRINT_APPLY:
                baseService.sendMessageToOne(MessageType.APPLY_APPROVE_MSG, "信函打印申请审批结果", "客户:" + personalName + "的信函打印申请审批" + approveResultStr, applyId);
                break;
            default:
                break;
        }
    }

    /**
     * @Author wangxiangdong
     * @Description 设置个流程节点审批结果
     * @Date 2019/10/18 13:52
     **/
    private void setProvessFlowNode(Set<ProcessFlowNode> processFlowNodes,ApprovalResult approvalResult,String remark){
        if(processFlowNodes.size()>0){
            processFlowNodes.forEach(processFlowNode -> {
                processFlowNode.setIsShow(BaseSelect.YES);
                processFlowNode.setApprovedResult(approvalResult);
                processFlowNode.setApprovalTime(ZWDateUtil.getNowDateTime());
                processFlowNode.setApprovalStatus(ApprovalStatus.APPROVED_COMPLETED);
                processFlowNode.setRemark(remark);
            });
        }
    }

    /**
     * @Author wangxiangdong
     * @Description 导出查账申请
     * @Date 2019/11/21 10:44
     **/
    public void getExportPaymentCheckTitle(ExportPaymentCheck exportPaymentCheck, String token) {
        UserModel userByToken = baseService.getUserByToken(token);
        UploadFile uploadFile = null;
        TaskBoxModel taskBoxModel = new TaskBoxModel();
        Snowflake snowflake = new Snowflake((int) (Thread.currentThread().getId() % 1024));
        taskBoxModel.setId(String.valueOf(snowflake.next()));
        baseService.sendTaskBoxMessage(taskBoxModel, TaskBoxType.EXPORT, TaskBoxStatus.UN_FINISH, null, null, userByToken, ZWDateUtil.getNowDateTime(), null, "申请类信息导出");
        List<Class<?>> objClassList = new ArrayList<>();
        List<CheckAccountModel> checkAccountModels;
        String fieldName = "";
        try {
            List<PaymentCheck> paymentCheckList = Lists.newArrayList(paymentCheckRepository.findAllById(exportPaymentCheck.getIds()));
            fieldName = fieldName.concat("查账申请导出_").concat(String.valueOf(System.currentTimeMillis())).concat(".xlsx");
            objClassList.add(CheckAccountModel.class);
            checkAccountModels = getCheckAccountData(paymentCheckList);
            uploadFile = exportData(taskBoxModel, userByToken, objClassList, checkAccountModels, fieldName);
        } catch (Exception e) {
            e.printStackTrace();
            baseService.sendTaskBoxMessage(taskBoxModel, TaskBoxType.EXPORT, TaskBoxStatus.FAILURE, uploadFile.getId(), uploadFile.getOriginalName(), userByToken, null, ZWDateUtil.getNowDateTime(), "申请类信息导出");
        }
        baseService.sendTaskBoxMessage(taskBoxModel, TaskBoxType.EXPORT, TaskBoxStatus.FINISHED, uploadFile.getId(), uploadFile.getOriginalName(), userByToken, null, ZWDateUtil.getNowDateTime(), "申请类信息导出");

    }

    private List<CheckAccountModel> getCheckAccountData(List<PaymentCheck> paymentCheckList) {
        List<CheckAccountModel> models = new ArrayList<>();
        for (PaymentCheck paymentCheck : paymentCheckList) {
            CheckAccountModel model = new CheckAccountModel();
            BeanUtils.copyProperties(paymentCheck, model);
            paymentCheck.setExportState(ExportState.EXPORTED);
            models.add(model);
        }
        if (paymentCheckList.size() > 0) {
            paymentCheckRepository.saveAll(paymentCheckList);
        }
        return models;
    }

    public void importPaymentCheck(String fileId, String token) {
        InputStream inputStream = approvalImportDataService.readFile(fileId);
        UserModel userModel = baseService.getUserByToken(token);
        List<Class<?>> objClassList = new ArrayList<>();
        objClassList.add(CheckAccountModel.class);
        importPaymentCheck(objClassList, inputStream, userModel);
    }

    private void importPaymentCheck(List<Class<?>> objClassList, InputStream inputStream, UserModel userModel) {
        List<Map<String, String>> sheetDataList = approvalImportDataService.parseApprovalImportData(inputStream);
        Map<String, ImportExcelConfigItem> headMap = approvalImportDataService.excelConfigItemToMap(sheetDataList, inputStream, objClassList);
            sheetDataList.remove(sheetDataList.get(0));
            List<String> errorList = new ArrayList<>();
            List<String> idList = new ArrayList<>();
            Map<String, CheckAccountModel> checkAccountModelMap = new HashMap<>();
            Long rowIndex = 1L;
            for (Map<String, String> map : sheetDataList) {
                CheckAccountModel object = new CheckAccountModel();
                for (Map.Entry<String, String> cellUnit : map.entrySet()) {
                    String cellValue = cellUnit.getValue();
                    ImportExcelConfigItem importExcelConfigItem = headMap.get(cellUnit.getKey());
                    approvalImportDataService.parseCellMap(object, cellValue, importExcelConfigItem, errorList, rowIndex, 1);
                }
                idList.add(object.getId());
                checkAccountModelMap.put(object.getId(), object);
                rowIndex++;
            }
            List<PaymentCheck> paymentCheckList = paymentCheckRepository.findAllById(idList);
            if (paymentCheckList.size() > 0) {
                for (PaymentCheck paymentCheck : paymentCheckList) {
                    if (checkAccountModelMap.containsKey(paymentCheck.getId())) {
                        CheckAccountModel checkAccountModel = checkAccountModelMap.get(paymentCheck.getId());
                        paymentCheck.setIsReply(BaseSelect.YES);
                        paymentCheck.setReplyName(userModel.getRealName());
                        paymentCheck.setReplyDate(ZWDateUtil.getNowDateTime());
                        paymentCheck.setOperator(userModel.getRealName());
                        paymentCheck.setHasPaymentAmt(checkAccountModel.getHasPaymentAmt());
                        paymentCheck.setHasPaymentDate(checkAccountModel.getHasPaymentDate());
                        paymentCheck.setOperatorDate(ZWDateUtil.getNowDateTime());
                        paymentCheck.setRemark(checkAccountModel.getRemark());
                        String content = "客户姓名为:[" + paymentCheck.getPersonalName() + "]的查账回复完成";
                        baseService.sendMessageToOne(MessageType.APPLY_APPROVE_MSG, "查账回复", content, paymentCheck.getApplyId());
                    }
                }
            }
            if (paymentCheckList.size() > 0) {
                paymentCheckRepository.saveAll(paymentCheckList);
            }
    }

}
